#ifndef __LT9211__H_
#define __LT9211__H_

// 连接数
#define LT9211_N_SINKS 4

// lane 数
#define LT9211_LANES               4LL
// BPP
#define LT9211_BITS_PER_SAMPLE     8LL

#define LT9211_XVCLK_FREQ          25000000


#define CHIP_ID_1                      0x21
#define CHIP_ID_2                      0x03
#define CHIP_ID_3                      0xE0
#define LT9211_REG_CHIP_ID_SIZE      0x03
#define LT9211_REG_CHIP_ID_1         0x00
#define LT9211_REG_CHIP_ID_2         0x01
#define LT9211_REG_CHIP_ID_3         0x02

// 下面3个寄存器已经配好了
#define LT9211_REG_CTRL_MODE       0x8a2
#define LT9211_MODE_SW_STANDBY     0x04
#define LT9211_MODE_STREAMING      0xf4

#define LT9211_REG_0               0x0000
#define LT9211_REMOTE_CTRL         0x000e
#define LT9211_REMOTE_DISABLE      0xF0
#define LT9211_REMOTE_ENABLE       0xFF

#define REG_NULL                     0xFFFF
// 本设备的地址
#define ADDR_THIS                    0xFF
// 串行器的地址，包括默认地址与1~4（新地址）
enum ADDR_SERIALIZER
{
    ADDR_SERIALIZER_POS = LT9211_N_SINKS,
    ADDR_SERIALIZER_DEF =  0x40,
    ADDR_SERIALIZER_0,
    ADDR_SERIALIZER_1,
    ADDR_SERIALIZER_2,
    ADDR_SERIALIZER_3,

    ADDR_SERIALIZER_4,
    ADDR_SERIALIZER_5,
    ADDR_SERIALIZER_6,
    ADDR_SERIALIZER_7
};

#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
#define OF_CAMERA_PINCTRL_STATE_SLEEP   "rockchip,camera_sleep"


#define LT9211_NAME              "lt9211"
#define LT9211_MEDIA_BUS_FMT     MEDIA_BUS_FMT_RGB888_1X24

#define I2C_RW_MAX_RETRY 2


enum config_action {
    CFG_REG,
    CFG_REG_LINK_DATA_RATE,
    CFG_CAMERAS,
    CFG_END,
};

// 下列值与supported_modes应当一对一匹配
enum LT9211_IMAGE_MODE_INDEX {
    IMAGE_MODE_1080P30,
    IMAGE_MODE_UNKNOW,
};

struct regval {
    u16 config_action;
    u16 i2c_addr;
    u16 reg;
    u8  val;
    u16 delay;
};

struct lt9211_mode {
    u32 width;
    u32 height;
    struct v4l2_fract max_fps;
    u32 hts_def;
    u32 vts_def;
    u32 exp_def;
    u32 link_freq_idx;
    u32 bpp;
    const struct regval *reg_list;
    const struct regval *sensor_reg_list;
    enum LT9211_IMAGE_MODE_INDEX image_mode;
    u32 max_cameras_cnt;
};

// 多路摄像头各使用一个VC，分辨率为1920 * 1080
static const struct regval lt9211_mipi_init_for_single_mode[] = {
    // Setup MAX9295A -> LT9211A --MIPI PORT A
    // Setup LT9211 Power
    {CFG_REG, ADDR_THIS, 0x0017, 0x04, 0},
    {CFG_REG, ADDR_THIS, 0x0019, 0x10, 0},
    // LT9211 To 3GBPS
    {CFG_REG, ADDR_THIS, 0x0010, 0x11, 0},
    {CFG_REG, ADDR_THIS, 0x0011, 0x11, 0},
    // Disable MIPI CSI-2
    {CFG_REG, ADDR_THIS, 0x040b, 0x00, 0},
    // Link Initiaion
    // Enable all 4 Links in GMSL2 mode
    {CFG_REG, ADDR_THIS, 0x0006, 0xff, 0},
    // Video Pipe Selection (as default  need not to change)"
    {CFG_REG, ADDR_THIS, 0x00f0, 0x62, 0},
    {CFG_REG, ADDR_THIS, 0x00f1, 0xea, 0},
    //----, 0x00, 0xF2, 0x51         // pipe Y in link B to video pipe 4  pipe Y in link A to video pipe 5
    //----, 0x00, 0xF3, 0xD9         // pipe Y in link D to video pipe 6  pipe Y in link C to video pipe 7
    // Turn on 4 pipes
    {CFG_REG, ADDR_THIS, 0x00f4, 0x0f, 0},

    // (optional) enable for max. bandwidth efficiency
    // ---- Enable bpp12 double mode for all controllers ---------
    //----, 0x09, 0x33, 0x01  // ALT_MEM_MAP12 = 1 on Ctrl 0
    //----, 0x09, 0x73, 0x01  // ALT_MEM_MAP12 = 1 on Ctrl 1
    //----, 0x09, 0xB3, 0x01  // ALT_MEM_MAP12 = 1 on Ctrl 2
    //----, 0x09, 0xF3, 0x01  // ALT_MEM_MAP12 = 1 on Ctrl 3

    // Efficiency updates (disable HEARTBEAT Mode) for image data pipes 0-3"
    {CFG_REG, ADDR_THIS, 0x0106, 0x0A, 0},
    {CFG_REG, ADDR_THIS, 0x0118, 0x0A, 0},
    {CFG_REG, ADDR_THIS, 0x012A, 0x0A, 0},
    {CFG_REG, ADDR_THIS, 0x013C, 0x0A, 0},
    // YUV422 8bit  video pipe 0  map FS/FE       （4个pipe 数据进到Controller 1 都在portA输出）
    {CFG_REG, ADDR_THIS, 0x090B, 0x07, 0},
    {CFG_REG, ADDR_THIS, 0x092D, 0x15, 0},  // map to MIPI Controller 1
    {CFG_REG, ADDR_THIS, 0x090D, 0x1e, 0},
    {CFG_REG, ADDR_THIS, 0x090E, 0x1e, 0},  // map to VC0
    {CFG_REG, ADDR_THIS, 0x090F, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x0910, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x0911, 0x01, 0},
    {CFG_REG, ADDR_THIS, 0x0912, 0x01, 0},


    // YUV422 8bit  video pipe 1  map FS/FE
    {CFG_REG, ADDR_THIS, 0x094B, 0x07, 0},
    {CFG_REG, ADDR_THIS, 0x096D, 0x15, 0},  // map to MIPI Controller 1
    {CFG_REG, ADDR_THIS, 0x094D, 0x1e, 0},
    {CFG_REG, ADDR_THIS, 0x094E, 0x5e, 0},  // map to VC1
    {CFG_REG, ADDR_THIS, 0x094F, 0x00, 0},  // frame start
    {CFG_REG, ADDR_THIS, 0x0950, 0x40, 0},
    {CFG_REG, ADDR_THIS, 0x0951, 0x01, 0},
    {CFG_REG, ADDR_THIS, 0x0952, 0x41, 0},


    // YUV422 8bit  video pipe 2  map FS/FE
    {CFG_REG, ADDR_THIS, 0x098B, 0x07, 0},
    {CFG_REG, ADDR_THIS, 0x09AD, 0x15, 0},  // map to MIPI Controller 1
    {CFG_REG, ADDR_THIS, 0x098D, 0x1e, 0},
    {CFG_REG, ADDR_THIS, 0x098E, 0x9e, 0},  // map to VC2
    {CFG_REG, ADDR_THIS, 0x098F, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x0990, 0x80, 0},
    {CFG_REG, ADDR_THIS, 0x0991, 0x01, 0},
    {CFG_REG, ADDR_THIS, 0x0992, 0x81, 0},


    // YUV422 8bit  video pipe 3  map FS/FE
    {CFG_REG, ADDR_THIS, 0x09CB, 0x07, 0},
    {CFG_REG, ADDR_THIS, 0x09ED, 0x15, 0},  // map to MIPI Controller 1
    {CFG_REG, ADDR_THIS, 0x09CD, 0x1e, 0},
    {CFG_REG, ADDR_THIS, 0x09CE, 0xde, 0},  // map to VC3
    {CFG_REG, ADDR_THIS, 0x09CF, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x09D0, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x09D1, 0x01, 0},
    {CFG_REG, ADDR_THIS, 0x09D2, 0xC1, 15},

    // MIPI PHY Setting"
    // Set Des in 2x4 mode  默认值
    // Set Lane Mapping for 4-lane port A。（有些没有数据  交换一下是E4或4E）
    {CFG_REG, ADDR_THIS, 0x08A3, 0xE4, 0},
    {CFG_REG, ADDR_THIS, 0x08A4, 0xE4, 0},
    // Set 4 lane D-PHY      默认值
    {CFG_REG, ADDR_THIS, 0x090A, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x094A, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x098A, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x09CA, 0xC0, 0},
    // Turn on MIPI PHYs
    {CFG_REG, ADDR_THIS, 0x08A2, 0xF0, 0},
    // Hold DPLL in reset (config_soft_rst_n = 0) before changing the rate
    //----, 0x1C, 0x00, 0xF4
    //----, 0x1D, 0x00, 0xF4
    //----, 0x1E, 0x00, 0xF4
    //----, 0x1F, 0x00, 0xF4
    {CFG_REG_LINK_DATA_RATE},

    // Release reset to DPLL (config_soft_rst_n = 1)
    //----, 0x1C, 0x00, 0xF5
    //----, 0x1D, 0x00, 0xF5
    //----, 0x1E, 0x00, 0xF5
    //----, 0x1F, 0x00, 0xF5

    {CFG_CAMERAS},

    // Enable all links back
    {CFG_REG, ADDR_THIS, 0x0006, 0xFF, 100},
    // One-shot link reset for all links
    {CFG_REG, ADDR_THIS, 0x0018, 0x0F, 20},

    // ------------- GMSL2 Sensor Settings -------------
    // PHY 2 copy PHY 0 output（数据从portA 复制到portB）
    {CFG_REG, ADDR_THIS, 0x08A9, 0xC8, 0}, //C0
    // PHY 3 copy PHY 1 output"
    {CFG_REG, ADDR_THIS, 0x08AA, 0xC8, 50}, //EA

    // Enable MIPI Output
    {CFG_REG, ADDR_THIS, 0x040B, 0x02, 0},
    {CFG_REG, ADDR_THIS, 0x08A0, 0x84, 500},

    {CFG_END}
};

// 多路摄像头使用一个VC，分辨率为7680(1920*4) * 1080
static const struct regval lt9211_mipi_init_for_4h1w_mode[] = {
    // Setup MAX9295A -> LT9211A --MIPI PORT A
    // Setup LT9211 Power
    {CFG_REG, ADDR_THIS, 0x0017, 0x04, 0},
    {CFG_REG, ADDR_THIS, 0x0019, 0x10, 0},
    // LT9211 To 3GBPS
    {CFG_REG, ADDR_THIS, 0x0010, 0x11, 0},
    {CFG_REG, ADDR_THIS, 0x0011, 0x11, 0},
    // Disable MIPI CSI-2
    {CFG_REG, ADDR_THIS, 0x040b, 0x00, 0},
    // Link Initiaion
    // Enable all 4 Links in GMSL2 mode
    {CFG_REG, ADDR_THIS, 0x0006, 0xff, 0},
    {CFG_REG, ADDR_THIS, 0x00f0, 0xea, 0},
    {CFG_REG, ADDR_THIS, 0x00f1, 0x62, 0},
    {CFG_REG, ADDR_THIS, 0x00f2, 0x73, 0},
    {CFG_REG, ADDR_THIS, 0x00f3, 0xfb, 0},
    //---- 0x00F2,0x51         // pipe Y in link B to video pipe 4  pipe Y in link A to video pipe 5
    //---- 0x00F3,0xD9         // pipe Y in link D to video pipe 6  pipe Y in link C to video pipe 7
    // Turn on 4 pipes
    {CFG_REG, ADDR_THIS, 0x00f4, 0x0f, 0},
    // (optional) enable for max. bandwidth efficiency
    // ---- Enable bpp12 double mode for all controllers ---------
    //---- 0x0933,0x01  // ALT_MEM_MAP12 = 1 on Ctrl 0
    //---- 0x0973,0x01  // ALT_MEM_MAP12 = 1 on Ctrl 1
    //---- 0x09B3,0x01  // ALT_MEM_MAP12 = 1 on Ctrl 2
    //---- 0x09F3,0x01  // ALT_MEM_MAP12 = 1 on Ctrl 3
    // Efficiency updates (disable HEARTBEAT Mode) for image data pipes 0-3
    {CFG_REG, ADDR_THIS, 0x0106, 0x0A, 0},
    {CFG_REG, ADDR_THIS, 0x0118, 0x0A, 0},
    {CFG_REG, ADDR_THIS, 0x012A, 0x0A, 0},
    {CFG_REG, ADDR_THIS, 0x013C, 0x0A, 100},
    // Side-by-Side (80 4hw, 00 w4h)"
    {CFG_REG, ADDR_THIS, 0x0931, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x0971, 0x0f, 0},
    {CFG_REG, ADDR_THIS, 0x09B1, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x09F1, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x0932, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x0972, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x09B2, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x09F2, 0x00, 0},
    {CFG_REG, ADDR_THIS, 0x08c6, 0x0F, 0},
    {CFG_REG, ADDR_THIS, 0x08c9, 0x00, 0},
    //{CFG_REG, ADDR_THIS, 0x0400,0x61
    //{CFG_REG, ADDR_THIS, 0x0400,0x65
    //{CFG_REG, ADDR_THIS, 0x0400,0x69
    //{CFG_REG, ADDR_THIS, 0x0400,0x6D
    // MIPI PHY Setting
    // Set Des in 2x4 mode  默认值
    // Set Lane Mapping for 4-lane port A。（有些没有数据  交换一下是E4或4E）
    {CFG_REG, ADDR_THIS, 0x08A3, 0xE4, 0},
    {CFG_REG, ADDR_THIS, 0x08A4, 0xE4, 0},
    // Set 4 lane D-PHY      默认值
    {CFG_REG, ADDR_THIS, 0x090A, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x094A, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x098A, 0xC0, 0},
    {CFG_REG, ADDR_THIS, 0x09CA, 0xC0, 0},
    // Turn on MIPI PHYs
    {CFG_REG, ADDR_THIS, 0x08A2, 0xF0, 0},
    // Hold DPLL in reset (config_soft_rst_n = 0) before changing the rate
    //---- 0x1C00,0xF4
    //---- 0x1D00,0xF4
    //---- 0x1E00,0xF4
    //---- 0x1F00,0xF4

    {CFG_REG_LINK_DATA_RATE},

    //Software-defined virtual channel for Pipe 3/2/1/0
    //{CFG_REG, ADDR_THIS, 0x040c 0x11
    //{CFG_REG, ADDR_THIS, 0x040d 0x11
    //set MFP2 to GPIO-08 TX
    {CFG_REG, ADDR_THIS, 0x0306, 0x83, 0},
    {CFG_REG, ADDR_THIS, 0x0307, 0xA8, 0},
    {CFG_REG, ADDR_THIS, 0x033d, 0x28, 0},
    {CFG_REG, ADDR_THIS, 0x0374, 0x28, 0},
    {CFG_REG, ADDR_THIS, 0x03aa, 0x28, 0},
    // Release reset to DPLL (config_soft_rst_n = 1)
    //---- 0x1C00,0xF5
    //---- 0x1D00,0xF5
    //---- 0x1E00,0xF5
    //---- 0x1F00,0xF5


    {CFG_CAMERAS},


    // Enable all links back
    {CFG_REG, ADDR_THIS, 0x0006, 0xF0, 100},
    // FSYNC: Auto
    //{CFG_REG, ADDR_THIS, 0x04 0xA0 0x06
    // FSYNC: Sem-Auto
    //FSYNC period
    {CFG_REG, ADDR_THIS,  0x04A5, 0xF8, 0},
    {CFG_REG, ADDR_THIS,  0x04A6, 0xC3, 0},
    {CFG_REG, ADDR_THIS,  0x04A7, 0x25, 0},
    //sync mode
    //{CFG_REG, ADDR_THIS, 0x1050, 0x10, 0},
    //{CFG_REG, ADDR_THIS, 0x1080, 0x10, 0},
    //{CFG_REG, ADDR_THIS, 0x1051, 0x1, 0},
    //{CFG_REG, ADDR_THIS, 0x1081, 0x1, 0},
    {CFG_REG, ADDR_THIS,  0x04A0, 0x0e, 0},
    {CFG_REG, ADDR_THIS,  0x04AF, 0xA1, 0},
    {CFG_REG, ADDR_THIS,  0x04A2, 0x1, 0},
    {CFG_REG, ADDR_THIS,  0x04A3, 0x0, 0},
    {CFG_REG, ADDR_THIS,  0x04A4, 0x0, 100},

    //  Enable all links back
    {CFG_REG, ADDR_THIS,  0x0006, 0xFF, 100},
    //  One-shot link reset for all links
    {CFG_REG, ADDR_THIS,  0x0018, 0x0F, 100},

    // ------------- GMSL2 Sensor Settings -------------
    // PHY 2 copy PHY 0 output（数据从portA 复制到portB）
    {CFG_REG, ADDR_THIS,  0x08A9,  0xC8, 0}, //C0
    // PHY 3 copy PHY 1 output
    {CFG_REG, ADDR_THIS,  0x08AA,  0xC8, 100}, //EA
    // Enable MIPI Output
    {CFG_REG, ADDR_THIS,  0x040B,  0x02, 0},
    {CFG_REG, ADDR_THIS,  0x08A0,  0x84, 0},
    //sleep 0.5
    //${MYSET} -f -y ${I2CBUS} w3@${I9295_ADDR_1} 0x02 0xd3 0x84
    // add by wdz switch 4wh
    {CFG_REG, ADDR_THIS,  0x971,   0x8f, 0},
    {CFG_END}
};

// 外同步(4h1w模式需要严格的同步信号，30HZ，5%的占空比)
static const struct regval max96717_1080p_reglist_external_sync [] = {
    // Camera reset
    {CFG_REG, ADDR_THIS, 0x02BE, 0x10, 100},
    // set DT
    {CFG_REG, ADDR_THIS, 0x0318, 0x5e, 0},
    {CFG_REG, ADDR_THIS, 0x02d3, 0x85, 0},
    {CFG_REG, ADDR_THIS, 0x0010, 0x21, 100},
    //RX_EN=1
    {CFG_REG, ADDR_THIS, 0x02d3, 0x84, 0},
    //RX GPIO-ID 0x1e
    {CFG_REG, ADDR_THIS, 0x02d5, 0x08, 0},
    {CFG_REG, ADDR_THIS, 0x024F, 0x01, 0},
    {CFG_REG, ADDR_THIS, 0x03E0, 0x30, 0},

    {CFG_END}
};

// 内同步(single模式不需要严格的外同步信号，内同步足以)
static const struct regval max96717_1080p_reglist_inside_sync [] = {
    // Camera reset
    {CFG_REG, ADDR_THIS, 0x02BE, 0x10, 100},
    // set DT
    {CFG_REG, ADDR_THIS, 0x0318, 0x5e, 0},
    // Inside Sync
    {CFG_REG, ADDR_THIS, 0x02d3, 0x00, 100},
    {CFG_REG, ADDR_THIS, 0x02d3, 0x10, 10},

    {CFG_END}
};

#if 0
static const s64 link_freq_items_1200MHZ[] = {
    LT9211_LINK_FREQ_1200MHZ,
};

static const s64 link_freq_items_2000MHZ[] = {
    LT9211_LINK_FREQ_2000MHZ,
};
#endif


#endif /* __LT9211__H_ */
